"""
学习能力增强服务
整合强化学习、增量学习、在线学习和知识演化功能
"""

import asyncio
from typing import Dict, Any, Optional
from datetime import datetime
import logging

from src.utils.logging import get_logger

logger = get_logger(__name__)


class LearningEnhancementService:
    """学习能力增强服务类"""
    
    def __init__(self):
        """初始化学习能力增强服务"""
        # 延迟导入以避免循环导入
        from src.containers import ServiceContainer
        
        # 获取依赖服务
        container = ServiceContainer()
        
        self.enhanced_rl_service = container.enhanced_reinforcement_learning_service()
        self.incremental_learning_service = container.incremental_learning_service()
        self.online_learning_service = container.online_learning_service()
        self.knowledge_evolution_service = container.knowledge_evolution_service()
        self.intelligent_decision_service = container.intelligent_decision_service()
        
        # 启动在线学习循环
        asyncio.create_task(self.online_learning_service.start_learning_loop())
        
        logger.info("学习能力增强服务初始化完成")
    
    async def process_user_interaction(self, user_id: int, interaction_data: Dict[str, Any]):
        """
        处理用户交互数据
        
        Args:
            user_id: 用户ID
            interaction_data: 交互数据
        """
        try:
            # 提交到在线学习服务
            await self.online_learning_service.submit_feedback({
                'user_id': user_id,
                'timestamp': datetime.utcnow(),
                **interaction_data
            })
            
            # 添加到增量学习缓冲区
            self.incremental_learning_service.add_training_sample({
                'user_id': user_id,
                'data': interaction_data,
                'timestamp': datetime.utcnow()
            })
            
            logger.debug(f"用户交互数据处理完成: 用户={user_id}")
            
        except Exception as e:
            logger.error(f"处理用户交互数据失败: {e}")
    
    def update_decision_model(self, user_id: int, question: str, context: Dict[str, Any], 
                             result: Dict[str, Any]) -> bool:
        """
        更新决策模型
        
        Args:
            user_id: 用户ID
            question: 问题
            context: 上下文
            result: 执行结果
            
        Returns:
            是否更新成功
        """
        try:
            # 提取状态特征
            state_features = self.intelligent_decision_service._extract_state_features({
                'question': question,
                'user_id': user_id,
                **context
            })
            
            # 获取用户偏好
            user_preferences = self.get_user_preferences(user_id)
            
            # 结合用户偏好调整状态特征
            if user_preferences:
                state_features['user_preference'] = self.intelligent_decision_service._analyze_user_preference(user_preferences)
            
            # 使用强化学习选择动作（用于获取执行的动作）
            action = self.enhanced_rl_service.get_action(state_features)
            
            # 更新决策模型
            success = self.intelligent_decision_service.update_decision_model(
                state_features, action, result
            )
            
            if success:
                logger.debug(f"决策模型更新成功: 用户={user_id}")
            else:
                logger.warning(f"决策模型更新失败: 用户={user_id}")
                
            return success
            
        except Exception as e:
            logger.error(f"更新决策模型失败: {e}")
            return False
    
    def get_user_preferences(self, user_id: int) -> Dict[str, Any]:
        """
        获取用户偏好
        
        Args:
            user_id: 用户ID
            
        Returns:
            用户偏好字典
        """
        # 这里应该调用用户偏好服务
        # 为简化实现，返回空字典
        return {}
    
    def evolve_knowledge_base(self):
        """演化知识库"""
        try:
            self.knowledge_evolution_service.evolve_knowledge()
            logger.info("知识库演化完成")
        except Exception as e:
            logger.error(f"知识库演化失败: {e}")
    
    def get_service_status(self) -> Dict[str, Any]:
        """
        获取服务状态
        
        Returns:
            服务状态信息
        """
        return {
            'enhanced_rl_service': {
                'q_table_size': len(self.enhanced_rl_service.q_table),
                'experience_buffer_size': len(self.enhanced_rl_service.experience_buffer)
            },
            'incremental_learning_service': self.incremental_learning_service.get_model_info(),
            'online_learning_service': self.online_learning_service.get_service_info(),
            'knowledge_evolution_service': self.knowledge_evolution_service.get_service_info()
        }
    
    async def shutdown(self):
        """关闭服务"""
        try:
            await self.online_learning_service.stop_learning_loop()
            logger.info("学习能力增强服务已关闭")
        except Exception as e:
            logger.error(f"关闭学习能力增强服务失败: {e}")


# A/B测试集成服务
class ABTestingIntegrationService:
    """A/B测试集成服务"""
    
    def __init__(self):
        """初始化A/B测试集成服务"""
        # 动态导入A/B测试相关模块
        try:
            from src.research_core.ab_testing import ABTester
            from src.research_core.multivariate_testing import MultivariateTester, OnlineABTester
            self.ab_tester = ABTester()
            self.mvt_tester = MultivariateTester()
            self.online_ab_tester = OnlineABTester()
            self.available = True
            logger.info("A/B测试集成服务初始化完成")
        except ImportError as e:
            logger.warning(f"A/B测试模块导入失败: {e}")
            self.available = False
    
    async def run_ab_test(self, prompt_variants: list, test_cases: list, 
                         evaluation_metrics: Optional[list] = None) -> Dict[str, Any]:
        """
        运行A/B测试
        
        Args:
            prompt_variants: 提示词变体列表
            test_cases: 测试用例列表
            evaluation_metrics: 评估指标列表
            
        Returns:
            测试结果
        """
        if not self.available:
            return {"error": "A/B测试服务不可用"}
            
        try:
            result = await self.ab_tester.run_ab_test(
                prompt_variants, test_cases, evaluation_metrics
            )
            return result
        except Exception as e:
            logger.error(f"A/B测试运行失败: {e}")
            return {"error": str(e)}
    
    async def run_mvt_test(self, factors: Dict[str, list], test_cases: list,
                          evaluation_metrics: Optional[list] = None) -> Dict[str, Any]:
        """
        运行多变量测试
        
        Args:
            factors: 因子字典
            test_cases: 测试用例列表
            evaluation_metrics: 评估指标列表
            
        Returns:
            测试结果
        """
        if not self.available:
            return {"error": "多变量测试服务不可用"}
            
        try:
            result = await self.mvt_tester.run_mvt_test(
                factors, test_cases, evaluation_metrics
            )
            return result
        except Exception as e:
            logger.error(f"多变量测试运行失败: {e}")
            return {"error": str(e)}
    
    def create_online_test(self, test_id: str, variants: list):
        """
        创建在线A/B测试
        
        Args:
            test_id: 测试ID
            variants: 变体列表
        """
        if not self.available:
            raise Exception("在线A/B测试服务不可用")
            
        self.online_ab_tester.create_test(test_id, variants)
    
    def assign_variant(self, user_id: str, test_id: str) -> str:
        """
        为用户分配变体
        
        Args:
            user_id: 用户ID
            test_id: 测试ID
            
        Returns:
            分配的变体
        """
        if not self.available:
            raise Exception("在线A/B测试服务不可用")
            
        return self.online_ab_tester.assign_variant(user_id, test_id)
    
    def record_interaction(self, user_id: str, test_id: str, interaction_data: Dict[str, Any]):
        """
        记录用户交互
        
        Args:
            user_id: 用户ID
            test_id: 测试ID
            interaction_data: 交互数据
        """
        if not self.available:
            raise Exception("在线A/B测试服务不可用")
            
        self.online_ab_tester.record_user_interaction(user_id, test_id, interaction_data)
    
    def get_test_results(self, test_id: str) -> Dict[str, Any]:
        """
        获取测试结果
        
        Args:
            test_id: 测试ID
            
        Returns:
            测试结果
        """
        if not self.available:
            return {"error": "在线A/B测试服务不可用"}
            
        return self.online_ab_tester.get_test_results(test_id)


def get_learning_enhancement_service():
    """获取学习能力增强服务实例"""
    return LearningEnhancementService()


def get_ab_testing_integration_service():
    """获取A/B测试集成服务实例"""
    return ABTestingIntegrationService()